﻿using System;
using System.Diagnostics;
using System.Net;

namespace Lightray.Hattrick.ChppLib
{
    public class TimeScraper
    {
        private static Func<DateTime>[] _timeSourceMethods = new Func<DateTime>[]
        {
            new Func<DateTime>(scrapeTimeAndDateDotCom),
            new Func<DateTime>(scrape24TimezonesDotCom),
            new Func<DateTime>(scrapeWorldTimeEngineDotCom),
            new Func<DateTime>(timeZoneGeniusDotCom),
            //new Func<DateTime>(timeGenieDotCom), -> does not have seconds
            //new Func<DateTime>(scrapeVisitSwedenDotCom), -> complicated scrape
            //new Func<DateTime>(scrapeGreenwichMeanTimeDotCom), -> complicated scrape
        };

        private static DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

        public static DateTime ScrapeTime()
        {
            try
            {
                int sourceIndex = new Random().Next() % _timeSourceMethods.Length;
                Debug.WriteLine("using source: " + _timeSourceMethods[sourceIndex].Method.Name);
                return _timeSourceMethods[sourceIndex]();
            }
            catch (Exception)
            {
                return DateTime.MinValue;
            }
        }

        private static string scrapeSource(string url)
        {
            using (WebClient wc = new WebClient())
                return wc.DownloadString(url);
        }

        private static string inBetween(string str, int start, int end)
        {
            return str.Substring(start + 1, end - start - 1);
        }

        private static DateTime scrape24TimezonesDotCom()
        {
            const string url = "http://24timezones.com/gettime2_cities2.php?city=15650";
            string scrape = scrapeSource(url);

            int pos = scrape.IndexOf('=');
            int endPos = scrape.IndexOf('&', pos);
            return UNIX_EPOCH.AddSeconds(Convert.ToDouble(inBetween(scrape, pos, endPos)));
        }

        private static DateTime scrapeWorldTimeEngineDotCom()
        {
            const string url = "http://worldtimeengine.com/dotime/sweden";
            string scrape = scrapeSource(url);

            int pos = scrape.IndexOf("registerComponents") + "registerComponents".Length;
            int endPos = scrape.IndexOf(',', pos);
            return UNIX_EPOCH.AddMilliseconds(Convert.ToDouble(inBetween(scrape, pos, endPos)));
        }

        private static DateTime scrapeTimeAndDateDotCom()
        {
            const string url = "http://www.timeanddate.com/worldclock/fullscreen.html?n=239";
            string scrape = scrapeSource(url);

            int pos = scrape.IndexOf("i_date") + "i_date".Length;
            int endPos = scrape.IndexOf('<', pos);
            DateTime datePart = DateTime.Parse(inBetween(scrape, pos, endPos));

            pos = scrape.IndexOf("i_time") + "i_time".Length;
            endPos = scrape.IndexOf('<', pos);
            DateTime timePart = DateTime.Parse(inBetween(scrape, pos, endPos));

            return new DateTime(datePart.Year, datePart.Month, datePart.Day,
                                timePart.Hour, timePart.Minute, timePart.Second);
        }

        private static DateTime timeZoneGeniusDotCom()
        {
            const string url = "http://www.timezonegenius.com/detail/sweden/stockholm";
            string scrape = scrapeSource(url);

            int pos = scrape.IndexOf("Offset = Date.parse(") + "Offset = Date.parse(".Length;
            int endPos = scrape.IndexOf("')", pos);
            return DateTime.Parse(inBetween(scrape, pos, endPos));
        }

        //private static DateTime timeGenieDotCom()
        //{
        //    const string url = "http://www.timegenie.com/city.time/sesto";
        //    string scrape = scrapeSource(url);

        //    int pos = scrape.IndexOf("<span class=\"time\">") + "<span class=\"time\">".Length;
        //    int endPos = scrape.IndexOf("<a", pos);
        //    DateTime timePart = DateTime.Parse(inBetween(scrape, pos, endPos));

        //    pos = scrape.IndexOf("<span class=\"day\">", endPos) + "<span class=\"day\">".Length;
        //    endPos = scrape.IndexOf("</span>", pos);
        //    DateTime datePart = DateTime.Parse(inBetween(scrape, pos, endPos));

        //    return new DateTime(datePart.Year, datePart.Month, datePart.Day,
        //                        timePart.Hour, timePart.Minute, timePart.Second);
        //}               
    }
}
